{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CUST_ID</th>\n",
       "      <th>GENDER</th>\n",
       "      <th>AGE</th>\n",
       "      <th>TENURE</th>\n",
       "      <th>CHANNEL</th>\n",
       "      <th>AUTOPAY</th>\n",
       "      <th>ARPB_3M</th>\n",
       "      <th>CALL_PARTY_CNT</th>\n",
       "      <th>DAY_MOU</th>\n",
       "      <th>AFTERNOON_MOU</th>\n",
       "      <th>NIGHT_MOU</th>\n",
       "      <th>AVG_CALL_LENGTH</th>\n",
       "      <th>BROADBAND</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>63</td>\n",
       "      <td>1</td>\n",
       "      <td>34</td>\n",
       "      <td>27</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>203</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.04</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>64</td>\n",
       "      <td>0</td>\n",
       "      <td>62</td>\n",
       "      <td>58</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>360</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1910.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>3.30</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>65</td>\n",
       "      <td>1</td>\n",
       "      <td>39</td>\n",
       "      <td>55</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>304</td>\n",
       "      <td>0</td>\n",
       "      <td>437.2</td>\n",
       "      <td>200.3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.92</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>66</td>\n",
       "      <td>1</td>\n",
       "      <td>39</td>\n",
       "      <td>55</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>304</td>\n",
       "      <td>0</td>\n",
       "      <td>437.2</td>\n",
       "      <td>182.8</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.92</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>67</td>\n",
       "      <td>1</td>\n",
       "      <td>39</td>\n",
       "      <td>55</td>\n",
       "      <td>3</td>\n",
       "      <td>0</td>\n",
       "      <td>304</td>\n",
       "      <td>0</td>\n",
       "      <td>437.2</td>\n",
       "      <td>214.5</td>\n",
       "      <td>0.0</td>\n",
       "      <td>4.92</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   CUST_ID  GENDER  AGE  TENURE  CHANNEL  AUTOPAY  ARPB_3M  CALL_PARTY_CNT  \\\n",
       "0       63       1   34      27        2        0      203               0   \n",
       "1       64       0   62      58        1        0      360               0   \n",
       "2       65       1   39      55        3        0      304               0   \n",
       "3       66       1   39      55        3        0      304               0   \n",
       "4       67       1   39      55        3        0      304               0   \n",
       "\n",
       "   DAY_MOU  AFTERNOON_MOU  NIGHT_MOU  AVG_CALL_LENGTH  BROADBAND  \n",
       "0      0.0            0.0        0.0             3.04          1  \n",
       "1      0.0         1910.0        0.0             3.30          1  \n",
       "2    437.2          200.3        0.0             4.92          0  \n",
       "3    437.2          182.8        0.0             4.92          0  \n",
       "4    437.2          214.5        0.0             4.92          0  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv('broadband.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1114 entries, 0 to 1113\n",
      "Data columns (total 13 columns):\n",
      "CUST_ID            1114 non-null int64\n",
      "GENDER             1114 non-null int64\n",
      "AGE                1114 non-null int64\n",
      "TENURE             1114 non-null int64\n",
      "CHANNEL            1114 non-null int64\n",
      "AUTOPAY            1114 non-null int64\n",
      "ARPB_3M            1114 non-null int64\n",
      "CALL_PARTY_CNT     1114 non-null int64\n",
      "DAY_MOU            1114 non-null float64\n",
      "AFTERNOON_MOU      1114 non-null float64\n",
      "NIGHT_MOU          1114 non-null float64\n",
      "AVG_CALL_LENGTH    1114 non-null float64\n",
      "BROADBAND          1114 non-null int64\n",
      "dtypes: float64(4), int64(9)\n",
      "memory usage: 113.2 KB\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### 参数说明\n",
    "本代码文件只为演示随机森林的用法和调优方法，所以数据参数我们只需关注最后一个 \n",
    "\n",
    "broadband 即可：0-离开，1-留存；\n",
    "\n",
    "其他自变量意思可不做探究，毕竟真实工作中的数据集也完全不一样。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cust_id</th>\n",
       "      <th>gender</th>\n",
       "      <th>age</th>\n",
       "      <th>tenure</th>\n",
       "      <th>channel</th>\n",
       "      <th>autopay</th>\n",
       "      <th>arpb_3m</th>\n",
       "      <th>call_party_cnt</th>\n",
       "      <th>day_mou</th>\n",
       "      <th>afternoon_mou</th>\n",
       "      <th>night_mou</th>\n",
       "      <th>avg_call_length</th>\n",
       "      <th>broadband</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1036</th>\n",
       "      <td>669</td>\n",
       "      <td>0</td>\n",
       "      <td>64</td>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>149</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>2.2</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      cust_id  gender  age  tenure  channel  autopay  arpb_3m  call_party_cnt  \\\n",
       "1036      669       0   64       3        1        0      149               0   \n",
       "\n",
       "      day_mou  afternoon_mou  night_mou  avg_call_length  broadband  \n",
       "1036      0.0            0.0        0.0              2.2          0  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 列名全部换成小写\n",
    "df.rename(str.lower, axis='columns', inplace=True)\n",
    "df.sample()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Broadband:  Counter({0: 908, 1: 206})\n"
     ]
    }
   ],
   "source": [
    "# 查看因变量 broadband 分布情况，看是否存在不平衡\n",
    "from collections import Counter\n",
    "print('Broadband: ', Counter(df['broadband'])) \n",
    "## Broadband:  Counter({0: 908, 1: 206}) 比较不平衡。\n",
    "## 根据原理部分，可知随机森林是处理数据不平衡问题的利器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 拆分测试集与训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = df['broadband'] \n",
    "X = df.iloc[:, 1:-1] \n",
    "# 客户 id 没有用，故丢弃 cust_id, \n",
    "## 0 可以表示第一列和最后一列，所以 1:-1 自动丢弃了第一列的客户 id 与最后一列的因变量\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, \n",
    "                                    test_size=0.4, random_state=12345)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 决策树建模\n",
    "为了对比随机森林效果，也可作为基础温习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sklearn.tree as tree\n",
    "\n",
    "# 直接使用交叉网格搜索来优化决策树模型，边训练边优化\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "# 网格搜索的参数：正常决策树建模中的参数 - 评估指标，树的深度，最小拆分的叶子样本数与树的深度\n",
    "param_grid = {'criterion': ['entropy', 'gini'],\n",
    "             'max_depth': [2, 3, 4, 5, 6, 7, 8],\n",
    "             'min_samples_split': [4, 8, 12, 16, 20, 24, 28]} \n",
    "                # 通常来说，十几层的树已经是比较深了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf = tree.DecisionTreeClassifier()  # 定义一棵树\n",
    "clfcv = GridSearchCV(estimator=clf, param_grid=param_grid, scoring='roc_auc',\n",
    "                    cv=4) # 传入模型，网格搜索的参数，评估指标，cv交叉验证的次数\n",
    "                          ## 这里也只是定义，还没有开始训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=4, estimator=DecisionTreeClassifier(),\n",
       "             param_grid={'criterion': ['entropy', 'gini'],\n",
       "                         'max_depth': [2, 3, 4, 5, 6, 7, 8],\n",
       "                         'min_samples_split': [4, 8, 12, 16, 20, 24, 28]},\n",
       "             scoring='roc_auc')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clfcv.fit(X=X_train, y=y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "决策树准确度:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.84      0.99      0.91       359\n",
      "           1       0.79      0.22      0.34        87\n",
      "\n",
      "    accuracy                           0.84       446\n",
      "   macro avg       0.82      0.60      0.62       446\n",
      "weighted avg       0.83      0.84      0.80       446\n",
      "\n",
      "决策树 AUC:\n",
      "AUC = 0.6022\n"
     ]
    }
   ],
   "source": [
    "# 使用模型来对测试集进行预测\n",
    "test_est = clfcv.predict(X_test)\n",
    "\n",
    "# 模型评估\n",
    "import sklearn.metrics as metrics\n",
    "\n",
    "print(\"决策树准确度:\")\n",
    "print(metrics.classification_report(y_test,test_est)) # 该矩阵表格其实作用不大\n",
    "print(\"决策树 AUC:\")\n",
    "fpr_test, tpr_test, th_test = metrics.roc_curve(y_test, test_est)\n",
    "print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))\n",
    "\n",
    "# AUC 大于 0.5 是最基本的要求，可见模型精度还是比较糟糕的\n",
    "# 决策树的调优技巧不多展开，将在随机森林调优部分展示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 随机森林建模"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 一样是直接使用网格搜索\n",
    "param_grid = {\n",
    "    'criterion':['entropy','gini'],\n",
    "    'max_depth':[5, 6, 7, 8],    # 深度：这里是森林中每棵决策树的深度\n",
    "    'n_estimators':[11,13,15],  # 决策树个数-随机森林特有参数\n",
    "    'max_features':[0.3,0.4,0.5], # 每棵决策树使用的变量占比-随机森林特有参数（结合原理）\n",
    "    'min_samples_split':[4,8,12,16]  # 叶子的最小拆分样本量\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sklearn.ensemble as ensemble # ensemble learning: 集成学习"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=4, estimator=RandomForestClassifier(),\n",
       "             param_grid={'criterion': ['entropy', 'gini'],\n",
       "                         'max_depth': [5, 6, 7, 8],\n",
       "                         'max_features': [0.3, 0.4, 0.5],\n",
       "                         'min_samples_split': [4, 8, 12, 16],\n",
       "                         'n_estimators': [11, 13, 15]},\n",
       "             scoring='roc_auc')"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rfc = ensemble.RandomForestClassifier()\n",
    "rfc_cv = GridSearchCV(estimator=rfc, param_grid=param_grid,\n",
    "                      scoring='roc_auc', cv=4)\n",
    "rfc_cv.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "随机森林精确度...\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.98      0.87      0.92       405\n",
      "           1       0.38      0.80      0.52        41\n",
      "\n",
      "    accuracy                           0.86       446\n",
      "   macro avg       0.68      0.84      0.72       446\n",
      "weighted avg       0.92      0.86      0.88       446\n",
      "\n",
      "随机森林 AUC...\n",
      "AUC = 0.8358\n"
     ]
    }
   ],
   "source": [
    "# 使用随机森林对测试集进行预测\n",
    "test_est = rfc_cv.predict(X_test)\n",
    "print('随机森林精确度...')\n",
    "print(metrics.classification_report(test_est, y_test))\n",
    "print('随机森林 AUC...')\n",
    "fpr_test, tpr_test, th_test = metrics.roc_curve(test_est, y_test) # 构造 roc 曲线\n",
    "print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))\n",
    "# AUC ，即预测类模型的精度大大提升"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'criterion': 'gini',\n",
       " 'max_depth': 8,\n",
       " 'max_features': 0.4,\n",
       " 'min_samples_split': 4,\n",
       " 'n_estimators': 15}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 查看最佳参数，看是否在决策边界上，还需重新设置网格搜索参数\n",
    "rfc_cv.best_params_\n",
    "\n",
    "# \"\"\"\n",
    "# 原来的参数\n",
    "# param_grid = {\n",
    "#     'criterion':['entropy','gini'],\n",
    "#     'max_depth':[5, 6, 7, 8],    # 深度：这里是森林中每棵决策树的深度\n",
    "#     'n_estimators':[11,13,15],  # 决策树个数-随机森林特有参数\n",
    "#     'max_features':[0.3,0.4,0.5], # 每棵决策树使用的变量占比-随机森林特有参数（结合原理）\n",
    "#     'min_samples_split':[4,8,12,16]  # 叶子的最小拆分样本量\n",
    "# }\n",
    "\n",
    "# 打印出来的最佳参数\n",
    "# {'criterion': 'gini',\n",
    "#  'max_depth': 8,  在最大值边界上，所以这个参数的最大值范围应该再调大\n",
    "#  'max_features': 0.5,  也在最大值边界上，说明这个参数的最小值范围应该再调大\n",
    "#  'min_samples_split': 4, 同理，在最小边界上，可考虑把范围调小\n",
    "#  'n_estimators': 15 同理，在最大边界上，可以适当调大范围}\n",
    "# \"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "随机森林精确度...\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.97      0.88      0.92       397\n",
      "           1       0.45      0.80      0.57        49\n",
      "\n",
      "    accuracy                           0.87       446\n",
      "   macro avg       0.71      0.84      0.75       446\n",
      "weighted avg       0.91      0.87      0.88       446\n",
      "\n",
      "随机森林 AUC...\n",
      "AUC = 0.8375\n"
     ]
    }
   ],
   "source": [
    "# 调整决策边界，这里只是做示范，实际业务中有时候调整一个上午也是正常的。\n",
    "param_grid = {\n",
    "    'criterion':['entropy','gini'],\n",
    "    'max_depth':[7, 8, 10, 12], # 前面的 5，6 也可以适当的去掉，反正已经没有用了\n",
    "    'n_estimators':[11, 13, 15, 17, 19],  #决策树个数-随机森林特有参数\n",
    "    'max_features':[0.4, 0.5, 0.6, 0.7], #每棵决策树使用的变量占比-随机森林特有参数\n",
    "    'min_samples_split':[2, 3, 4, 8, 12, 16]  # 叶子的最小拆分样本量\n",
    "}\n",
    "\n",
    "# 重复上述步骤，可写成函数供快捷调用\n",
    "rfc_cv = GridSearchCV(estimator=rfc, param_grid=param_grid,\n",
    "                      scoring='roc_auc', cv=4)\n",
    "rfc_cv.fit(X_train, y_train)\n",
    "# 使用随机森林对测试集进行预测\n",
    "test_est = rfc_cv.predict(X_test)\n",
    "print('随机森林精确度...')\n",
    "print(metrics.classification_report(test_est, y_test))\n",
    "print('随机森林 AUC...')\n",
    "fpr_test, tpr_test, th_test = metrics.roc_curve(test_est, y_test) # 构造 roc 曲线\n",
    "print('AUC = %.4f' %metrics.auc(fpr_test, tpr_test))\n",
    "# 这里的 auc 只提升了一点点，在实际情况中有时候能得到如 0.5 这样很不错的提升"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'criterion': 'gini',\n",
       " 'max_depth': 12,\n",
       " 'max_features': 0.6,\n",
       " 'min_samples_split': 2,\n",
       " 'n_estimators': 19}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rfc_cv.best_params_ "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
